Option Explicit On

'Copyright (c) 2007-2010, William Severance, Jr., WESNet Designs
'All rights reserved.

'Redistribution and use in source and binary forms, with or without modification, are permitted
'provided that the following conditions are met:

'Redistributions of source code must retain the above copyright notice, this list of conditions
'and the following disclaimer.

'Redistributions in binary form must reproduce the above copyright notice, this list of conditions
'and the following disclaimer in the documentation and/or other materials provided with the distribution.

'Neither the name of William Severance, Jr. or WESNet Designs may be used to endorse or promote
'products derived from this software without specific prior written permission.

'Disclaimer: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
'            OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
'            AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE
'            FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
'            LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
'            INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
'            OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
'            IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

'Although I will try to answer questions regarding the installation and use of this software when
'such questions are submitted via e-mail to the below address, no promise of further
'support or enhancement is made nor should be assumed.

'Developer Contact Information:
'     William Severance, Jr.
'     WESNet Designs
'     679 Upper Ridge Road
'     Bridgton, ME 04009
'     Phone: 207-647-9375
'     E-Mail: bill@wesnetdesigns.com
'     Website: www.wesnetdesigns.com

Imports System
Imports System.Configuration
Imports System.Data
Imports System.Xml
Imports System.Web
Imports System.Collections.Generic
Imports DotNetNuke
Imports DotNetNuke.Entities.Users
Imports DotNetNuke.Entities.Modules
Imports DotNetNuke.Services.Search
Imports DotNetNuke.Common.Utilities
Imports DotNetNuke.Common.Utilities.XmlUtils
Imports DotNetNuke.Services.Exceptions
Imports DotNetNuke.Security


Imports System.IO

Namespace WESNet.DNN.Modules.EPrayer
  Public Class EPrayerController
    Implements Entities.Modules.ISearchable
    Implements Entities.Modules.IPortable
    Implements Entities.Modules.IUpgradeable


#Region "Public Methods"

#Region "Categories"
    Public Function GetCategories(ByVal ModuleID As Integer) As List(Of CategoryInfo)
      Return CBO.FillCollection(Of CategoryInfo)(DataProvider.Instance().GetCategories(ModuleID))
    End Function

    Public Function GetCategory(ByVal CategoryID As Integer) As CategoryInfo
      Return CBO.FillObject(Of CategoryInfo)(DataProvider.Instance().GetCategory(CategoryID))
    End Function

    Public Function GetCategoryName(ByVal CategoryID As Integer) As String
      Return GetCategory(CategoryID).Category
    End Function

    Public Sub AddCategory(ByVal objCategory As CategoryInfo)
      DataProvider.Instance().AddCategory(objCategory)
    End Sub

    Public Sub UpdateCategory(ByVal objCategory As CategoryInfo)
      DataProvider.Instance().UpdateCategory(objCategory)
    End Sub

    Public Sub DeleteCategory(ByVal CategoryID As Integer)
      DataProvider.Instance().DeleteCategory(CategoryID)
    End Sub
#End Region

#Region "Stati"
    Public Function GetStati() As List(Of StatusInfo)
      Return CBO.FillCollection(Of StatusInfo)(DataProvider.Instance().GetStati)
    End Function

    Public Function GetStatus(ByVal StatusID As Integer) As StatusInfo
      Return CBO.FillObject(Of StatusInfo)(DataProvider.Instance().GetStatus(StatusID))
    End Function

    Public Sub AddStatus(ByVal objStatus As StatusInfo)
      DataProvider.Instance().AddStatus(objStatus)
    End Sub

    Public Sub UpdateStatus(ByVal objStatus As StatusInfo)
      DataProvider.Instance().UpdateStatus(objStatus)
    End Sub

    Public Sub DeleteStatus(ByVal StatusID As Integer)
      DataProvider.Instance().DeleteStatus(StatusID)
    End Sub
#End Region

#Region "Relationships"
    Public Function GetRelationships() As List(Of RelationshipInfo)
      Return CBO.FillCollection(Of RelationshipInfo)(DataProvider.Instance().GetRelationships)
    End Function

    Public Function GetRelationship(ByVal RelationshipID As Integer) As RelationshipInfo
      Return CBO.FillObject(Of RelationshipInfo)(DataProvider.Instance().GetRelationship(RelationshipID))
    End Function

    Public Sub AddRelationship(ByVal objRelationship As RelationshipInfo)
      DataProvider.Instance().AddRelationship(objRelationship)
    End Sub

    Public Sub UpdateRelationship(ByVal objRelationship As RelationshipInfo)
      DataProvider.Instance().UpdateRelationship(objRelationship)
    End Sub

    Public Sub DeleteRelationship(ByVal RelationshipID As Integer)
      DataProvider.Instance().DeleteRelationship(RelationshipID)
    End Sub
#End Region

#Region "ChurchRelationships"
    Public Function GetChurchRelationships() As List(Of ChurchRelationshipInfo)
      Return CBO.FillCollection(Of ChurchRelationshipInfo)(DataProvider.Instance().GetChurchRelationships)
    End Function

    Public Function GetChurchRelationship(ByVal ChurchRelationshipID As Integer) As ChurchRelationshipInfo
      Return CBO.FillObject(Of ChurchRelationshipInfo)(DataProvider.Instance().GetChurchRelationship(ChurchRelationshipID))
    End Function

    Public Sub AddChurchRelationship(ByVal objChurchRelationship As ChurchRelationshipInfo)
      DataProvider.Instance().AddChurchRelationship(objChurchRelationship)
    End Sub

    Public Sub UpdateChurchRelationship(ByVal objChurchRelationship As ChurchRelationshipInfo)
      DataProvider.Instance().UpdateChurchRelationship(objChurchRelationship)
    End Sub

    Public Sub DeleteChurchRelationship(ByVal ChurchRelationshipID As Integer)
      DataProvider.Instance().DeleteChurchRelationship(ChurchRelationshipID)
    End Sub
#End Region

#Region "Distributions"
    Public Function GetDistributions(ByVal ModuleID As Integer) As List(Of DistributionInfo)
      Return CBO.FillCollection(Of DistributionInfo)(DataProvider.Instance().GetDistributions(ModuleID))
    End Function

    Public Function GetDistribution(ByVal DistributionID As Integer) As DistributionInfo
      Return CBO.FillObject(Of DistributionInfo)(DataProvider.Instance().GetDistribution(DistributionID))
    End Function

    Public Sub AddDistribution(ByVal objDistribution As DistributionInfo)
      DataProvider.Instance().AddDistribution(objDistribution)
    End Sub

    Public Sub UpdateDistribution(ByVal objDistribution As DistributionInfo)
      DataProvider.Instance().UpdateDistribution(objDistribution)
    End Sub

    Public Sub DeleteDistribution(ByVal DistributionID As Integer)
      DataProvider.Instance().DeleteDistribution(DistributionID)
    End Sub
#End Region

#Region "Requests"

    Public Function GetRequests(ByVal ModuleID As Integer, ByVal UserID As Integer, ByRef TotalRecords As Integer) As List(Of RequestInfo)
      Return GetRequests(ModuleID, &HFFFF, String.Empty, False, "Order_Date_DESC", UserID, 0, 0, TotalRecords)
    End Function

    Public Function GetRequests(ByVal ModuleID As Integer, ByVal Filter As String, ByVal UserID As Integer, ByRef TotalRecords As Integer) As List(Of RequestInfo)
      Return GetRequests(ModuleID, &HFFFF, Filter, False, "Order_Date_DESC", UserID, 0, 0, TotalRecords)
    End Function

    Public Function GetRequests(ByVal ModuleID As Integer, ByVal Distributions As Integer, ByVal Filter As String, ByVal IncludeExpired As Boolean, ByVal OrderBy As String, ByVal UserID As Integer, _
                                ByVal PageSize As Integer, ByVal PageIndex As Integer, ByRef TotalRecords As Integer) As List(Of RequestInfo)

      Return CBO.FillCollection(Of RequestInfo)(DataProvider.Instance().GetRequests(ModuleID, Distributions, Filter, IncludeExpired, OrderBy, UserID, PageSize, PageIndex), TotalRecords)
    End Function

    Public Function GetExpiredRequests(ByVal ModuleID As Integer, ByVal Filter As String, ByVal OrderBy As String, ByVal UserID As Integer, _
                                ByVal PageSize As Integer, ByVal PageIndex As Integer, ByRef TotalRecords As Integer) As List(Of RequestInfo)

      Return CBO.FillCollection(Of RequestInfo)(DataProvider.Instance().GetExpiredRequests(ModuleID, Filter, OrderBy, UserID, PageSize, PageIndex), TotalRecords)
    End Function

    Public Function GetRequest(ByVal RequestID As Integer, ByVal UserID As Integer, ByVal HydrateUpdates As Boolean) As RequestInfo
      Dim objRequest As RequestInfo = Nothing
      Dim dr As IDataReader = Nothing
      Try
        dr = DataProvider.Instance().GetRequest(RequestID, UserID, HydrateUpdates)
        If dr.Read Then
          objRequest = CBO.FillObject(Of RequestInfo)(dr, False)
          If HydrateUpdates AndAlso dr.NextResult Then
            Me.HydrateUpdates(objRequest, dr, False)
          End If
        End If
      Finally
        If Not dr Is Nothing AndAlso Not dr.IsClosed Then dr.Close()
      End Try
      Return objRequest
    End Function

    Public Sub UpdateRequest(ByVal objRequest As RequestInfo)
      DataProvider.Instance().UpdateRequest(objRequest)
    End Sub

    Public Sub UpdateRequestStatus(ByVal RequestID As Integer, ByVal StatusID As Integer, ByVal Expires As DateTime, ByVal IsLocked As Boolean)
      DataProvider.Instance().UpdateRequestStatus(RequestID, StatusID, Expires, IsLocked)
    End Sub

    Public Sub IncrementRequestViews(ByVal RequestID As Integer)
      DataProvider.Instance().IncrementRequestViews(RequestID)
    End Sub

    Public Function GetNewRequests(ByVal ModuleID As Integer, ByVal DaysForNew As Integer, ByVal MaxRows As Integer, ByVal UserID As Integer) As List(Of NewPostInfo)
      Return CBO.FillCollection(Of NewPostInfo)(DataProvider.Instance().GetNewRequests(ModuleID, DaysForNew, MaxRows, UserID))
    End Function

#End Region

#Region "Posts"
    Public Function GetPost(ByVal PostID As Integer) As PostInfo
      Return CBO.FillObject(Of PostInfo)(DataProvider.Instance().GetPost(PostID))
    End Function

    Public Function GetPosts(ByVal RequestID As Integer, ByVal Distributions As Integer, ByVal GetOnlyUpdates As Boolean) As List(Of PostInfo)
      Return CBO.FillCollection(Of PostInfo)(DataProvider.Instance().GetPosts(RequestID, Distributions, GetOnlyUpdates))
    End Function

    Public Sub HydrateUpdates(ByVal objRequestInfo As RequestInfo, ByVal dr As IDataReader, ByVal CloseDataReader As Boolean)
      If Not objRequestInfo Is Nothing Then
        CBO.FillCollection(Of PostInfo)(dr, objRequestInfo.Posts, CloseDataReader)
      End If
    End Sub

    Public Function AddPost(ByVal objRequest As RequestInfo, ByVal objPost As PostInfo, _
                            ByVal CreatedByUserID As Integer, ByVal CreatedOnDate As DateTime,
                            ByVal LastModifiedByUserID As Integer, ByVal LastModifiedOnDate As DateTime) As Integer
      Dim postID As Integer = DataProvider.Instance().AddPost(objRequest, objPost, CreatedByUserID, CreatedOnDate, LastModifiedByUserID, LastModifiedOnDate)
      If objRequest.RequestID = Null.NullInteger Then
        objRequest.RequestID = postID
      End If
      Return postID
    End Function

    Public Function AddPost(ByVal objRequest As RequestInfo, ByVal objPost As PostInfo, ByVal UserID As Integer) As Integer
      Return AddPost(objRequest, objPost, UserID, Null.NullDate, Null.NullInteger, Null.NullDate)
    End Function

    Public Sub UpdatePost(ByVal objPost As PostInfo, ByVal UserID As Integer)
      DataProvider.Instance().UpdatePost(objPost, UserID)
    End Sub

    Public Sub DeletePost(ByVal PostID As Integer)
      DataProvider.Instance().DeletePost(PostID)
    End Sub

    Public Function GetNewUpdates(ByVal ModuleID As Integer, ByVal DaysForNew As Integer, ByVal MaxRows As Integer, ByVal UserID As Integer) As List(Of NewPostInfo)
      Return CBO.FillCollection(Of NewPostInfo)(DataProvider.Instance().GetNewUpdates(ModuleID, DaysForNew, MaxRows, UserID))
    End Function

    Public Function GetMyPosts(ByVal ModuleID As Integer, ByVal UserID As Integer, ByVal OrderBy As String, _
                                ByVal PageSize As Integer, ByVal PageIndex As Integer, ByRef TotalRecords As Integer) As List(Of MyPostInfo)

      Return CBO.FillCollection(Of MyPostInfo)(DataProvider.Instance().GetMyPosts(ModuleID, UserID, OrderBy, PageSize, PageIndex), TotalRecords)
    End Function

    Public Sub ClearNotifySubject(ByVal PostID As Integer)
      DataProvider.Instance().ClearNotifySubject(PostID)
    End Sub
#End Region

#Region "Users"

    Public Sub IncrementUserVisits(ByVal ModuleID As Integer, ByVal UserID As Integer)
      DataProvider.Instance.IncrementUserVisits(ModuleID, UserID)
    End Sub

    Public Function GetUsers(ByVal ModuleID As Integer, ByRef TotalRecords As Integer) As List(Of UserInfo)
      Return GetUsers(ModuleID, String.Empty, "Username", 0, 0, TotalRecords)
    End Function

    Public Function GetUsers(ByVal ModuleID As Integer, ByVal OrderBy As String, ByRef TotalRecords As Integer) As List(Of UserInfo)
      Return GetUsers(ModuleID, String.Empty, OrderBy, 0, 0, TotalRecords)
    End Function

    Public Function GetUsers(ByVal ModuleID As Integer, ByVal Filter As String, ByVal OrderBy As String, ByRef TotalRecords As Integer) As List(Of UserInfo)
      Return GetUsers(ModuleID, Filter, OrderBy, 0, 0, TotalRecords)
    End Function

    Public Function GetUsers(ByVal ModuleID As Integer, ByVal Filter As String, ByVal OrderBy As String, _
                             ByVal PageSize As Integer, ByVal PageIndex As Integer, _
                             ByRef TotalRecords As Integer) As List(Of UserInfo)

      Dim dr As IDataReader = DataProvider.Instance().GetUsers(ModuleID, Filter, OrderBy, PageSize, PageIndex)
      Dim objUsers As New List(Of UserInfo)
      If Not dr Is Nothing Then
        Try
          While dr.Read
            objUsers.Add(FillUser(dr, False))
          End While
          Try
            dr.NextResult()
            If dr.Read Then
              TotalRecords = Convert.ToInt32(dr("TotalRecords"))
            Else
              TotalRecords = objUsers.Count
            End If
          Catch ex As Exception
            TotalRecords = objUsers.Count
          End Try
        Finally
          If Not dr.IsClosed Then dr.Close()
        End Try
      End If
      Return objUsers

    End Function

    Public Sub ClearUserCache(ByVal ModuleId As Integer, ByVal UserId As Integer)
      Dim CacheKey As String = String.Format(Consts.UserCacheKey, ModuleId, UserId)
      DataCache.RemoveCache(CacheKey)
    End Sub

    Public Function GetUser(ByVal ModuleId As Integer, ByVal UserID As Integer) As UserInfo
      Return GetUser(ModuleId, UserID, False)
    End Function

    Public Function GetUser(ByVal ModuleId As Integer, ByVal UserID As Integer, ByVal IgnoreCache As Boolean) As UserInfo
      Dim ui As UserInfo = Nothing
      Dim CacheKey As String = String.Format(Consts.UserCacheKey, ModuleId, UserID)
      If Not IgnoreCache Then ui = CType(DataCache.GetCache(CacheKey), UserInfo)

      If ui Is Nothing Then
        Dim mc As New ModuleController
        Dim settings As Hashtable = mc.GetModuleSettings(ModuleId)
        Dim PageSize As Integer = 10
        Dim OrderBy As String = "Order_Date_DESC"
        Dim MailFormat As DotNetNuke.Services.Mail.MailFormat = DotNetNuke.Services.Mail.MailFormat.Text
        Dim ViewableDistributions As Integer = 1
        Dim IsTrusted As Boolean
        If Not settings Is Nothing Then
          PageSize = Utilities.GetSettingValue(settings("PageSize"), PageSize)
          OrderBy = Utilities.GetSettingValue(settings("OrderBy"), OrderBy)
          MailFormat = Utilities.GetSettingValue(settings("MailFormat"), DotNetNuke.Services.Mail.MailFormat.Text)
        End If
        If UserID = -1 Then
          ui = New UserInfo(ModuleId)
          If Not settings Is Nothing Then
            ViewableDistributions = Utilities.GetSettingValue(settings("AnonymousUsersViewableDistributions"), 1)
          End If
          With ui
            .PageSize = PageSize
            .OrderBy = OrderBy
            .MailFormat = MailFormat
            .ViewableDistributions = ViewableDistributions
          End With
        Else
          ui = FillUser(DataProvider.Instance().GetUser(ModuleId, UserID), True)
          If ui Is Nothing Then

            ' get the DNN UserInfo for this UserID
            Dim PortalId As Integer = PortalController.GetCurrentPortalSettings.PortalId
            Dim uc As New UserController
            Dim DNNui As DotNetNuke.Entities.Users.UserInfo = uc.GetUser(PortalId, UserID)
            If Not DNNui Is Nothing Then
              ' add the EPrayer user to the database
              Try
                Dim rc As New DotNetNuke.Security.Roles.RoleController
                DNNui.Roles = rc.GetRolesByUser(UserID, PortalId)
                Dim ps As PortalSettings = DotNetNuke.Common.Globals.GetPortalSettings()
                If DNNui.IsInRole(ps.AdministratorRoleName) Then
                  IsTrusted = True
                  ViewableDistributions = &H7FFF
                Else
                  If Not settings Is Nothing Then
                    IsTrusted = Utilities.GetSettingValue(settings("NewUsersAreTrusted"), False)
                    ViewableDistributions = Utilities.GetSettingValue(settings("NewUsersViewableDistributions"), 1)
                  End If
                End If
                AddUser(ModuleId, UserID, DNNui.Username, PageSize, OrderBy, MailFormat, ViewableDistributions, IsTrusted)
                ui = FillUser(DataProvider.Instance().GetUser(ModuleId, UserID), True)
              Catch Exc As System.Exception
                LogException(Exc)
              End Try
            End If
            If ui Is Nothing Then 'shouldn't happen unless DNN user was deleted while he/she was logged on - but, to be safe
              ui = New UserInfo(ModuleId)
            End If
          End If
        End If
        DataCache.SetCache(CacheKey, ui, New TimeSpan(0, 0, Consts.UserCacheDuration))
      End If
      Return ui
    End Function

    Public Function GetUser(ByVal ModuleId As Integer, ByVal [Alias] As String) As UserInfo
      Return FillUser(DataProvider.Instance().GetUser(ModuleId, [Alias]), True)
    End Function

    Public Sub AddUser(ByVal ModuleID As Integer, ByVal UserID As Integer, ByVal [Alias] As String, ByVal PageSize As Integer, ByVal OrderBy As String, _
                       ByVal MailFormat As DotNetNuke.Services.Mail.MailFormat, ByVal ViewableDistributions As Integer, ByVal IsTrusted As Boolean)
      DataProvider.Instance().AddUser(ModuleID, UserID, [Alias], PageSize, OrderBy, MailFormat, ViewableDistributions, IsTrusted)
    End Sub

    Public Sub UpdateUser(ByVal objUser As UserInfo)
      DataProvider.Instance().UpdateUser(objUser)
    End Sub

    Public Sub DeleteUser(ByVal ModuleId As Integer, ByVal UserID As Integer)
      DataProvider.Instance().DeleteUser(ModuleId, UserID)
    End Sub

#End Region

#Region "Tracking"
    Public Sub StartEndTrackingAllPosts(ByVal ModuleID As Integer, ByVal UserID As Integer, ByVal Start As Boolean)
      DataProvider.Instance().StartEndAllPostsTracking(ModuleID, UserID, Start)
    End Sub

    Public Sub StartTrackingAllPosts(ByVal ModuleID As Integer, ByVal UserID As Integer)
      StartEndTrackingAllPosts(ModuleID, UserID, True)
    End Sub

    Public Sub EndTrackingAllPosts(ByVal ModuleID As Integer, ByVal UserID As Integer)
      StartEndTrackingAllPosts(ModuleID, UserID, False)
    End Sub

    Public Sub StartEndRequestTracking(ByVal RequestID As Integer, ByVal UserID As Integer, ByVal Start As Boolean)
      DataProvider.Instance().StartEndRequestTracking(RequestID, UserID, Start)
    End Sub

    Public Sub StartRequestTracking(ByVal RequestID As Integer, ByVal UserID As Integer)
      StartEndRequestTracking(RequestID, UserID, True)
    End Sub

    Public Sub EndRequestTracking(ByVal RequestID As Integer, ByVal UserID As Integer)
      StartEndRequestTracking(RequestID, UserID, False)
    End Sub

    Public Function GetTrackingEMails(ByVal PostID As Integer) As Generic.List(Of String)
      Dim EmailList As New Generic.List(Of String)
      Dim dr As IDataReader = DataProvider.Instance().GetTrackingEmails(PostID)
      Dim Email As String

      Try
        If Not dr Is Nothing Then
          While dr.Read
            Email = Convert.ToString(dr.Item("Email"))
            If EmailList.IndexOf(Email) = -1 Then EmailList.Add(Email)
          End While
        End If
      Finally
        If Not dr.IsClosed Then dr.Close()
      End Try
      Return EmailList
    End Function
#End Region

#Region "Moderators"

    Public Function IsModerator(ByVal ModuleID As Integer, ByVal UserID As Integer) As Boolean
      Return DataProvider.Instance.IsModerator(ModuleID, UserID)
    End Function

    Public Function GetModerator(ByVal ModuleID As Integer, ByVal UserID As Integer) As ModeratorInfo
      Return CBO.FillObject(Of ModeratorInfo)(DataProvider.Instance().GetModerator(ModuleID, UserID), True)
    End Function

    Public Function GetModerators(ByVal ModuleID As Integer, ByVal GetActiveOnly As Boolean) As List(Of ModeratorInfo)
      Return CBO.FillCollection(Of ModeratorInfo)(DataProvider.Instance().GetModerators(ModuleID, GetActiveOnly))
    End Function

    Public Sub AddModerator(ByVal ModuleID As Integer, ByVal UserID As Integer, ByVal ExpiresDate As DateTime)
      DataProvider.Instance().AddModerator(ModuleID, UserID, ExpiresDate)
    End Sub

    Public Sub UpdateModerator(ByVal ModuleID As Integer, ByVal UserID As Integer, ByVal ExpiresDate As DateTime, ByVal IsSuspended As Boolean)
      DataProvider.Instance().UpdateModerator(ModuleID, UserID, ExpiresDate, IsSuspended)
    End Sub

    Public Sub DeleteModerator(ByVal ModuleId As Integer, ByVal UserID As Integer)
      DataProvider.Instance().DeleteModerator(ModuleId, UserID)
    End Sub

    Public Function GetModeratorEMails(ByVal PostID As Integer) As Generic.List(Of String)

      Dim emailList As New List(Of String)
      Dim dr As IDataReader = DataProvider.Instance().GetModeratorEmails(PostID)
      Dim email As String

      Try
        If Not dr Is Nothing Then
          While dr.Read
            email = Convert.ToString(dr.Item("Email"))
            emailList.Add(email)
          End While
        End If
      Finally
        If Not dr.IsClosed Then dr.Close()
      End Try
      Return emailList
    End Function
#End Region

#Region "Moderation"
    Public Function GetPostsToModerate(ByVal ModuleID As Integer) As Generic.List(Of PostInfo)
      Return CBO.FillCollection(Of PostInfo)(DataProvider.Instance().GetPostsToModerate(ModuleID))
    End Function

    Public Sub ModerateApprovePost(ByVal PostID As Integer, ByVal ApprovedBy As Integer)
      DataProvider.Instance().ModerateApprovePost(PostID, ApprovedBy)
    End Sub

    Public Sub ModerateRejectPost(ByVal PostID As Integer, ByVal RejectedBy As Integer)
      DataProvider.Instance().ModerateRejectPost(PostID, RejectedBy)
    End Sub

    Public Sub ModerateUnapprovePost(ByVal PostID As Integer, ByVal UnapprovedBy As Integer)
      DataProvider.Instance().ModerateUnapprovePost(PostID, UnapprovedBy)
    End Sub
#End Region

#Region "MasterModules and Agregators"
    Public Function GetAvailableMasterModules(ByVal PortalID As Integer, ByVal AgregatorModuleID As Integer) As List(Of MasterModuleInfo)
      Return CBO.FillCollection(Of MasterModuleInfo)(DataProvider.Instance().GetAvailableMasterModules(PortalID, AgregatorModuleID))
    End Function

    Public Sub SaveAgregators(ByVal AgregatorModuleID As Integer, ByVal MasterModuleIds As String)
      DataProvider.Instance().SaveAgregators(AgregatorModuleID, MasterModuleIds)
    End Sub
#End Region

#Region "Stats"
    Public Sub InitializeStats(ByVal ModuleID As Integer)
      DataProvider.Instance().InitializeStats(ModuleID)
    End Sub

    Public Overloads Function GetStats(ByVal ModuleID As Integer) As Stats
      Return GetStats(ModuleID, -1)
    End Function

    Public Overloads Function GetStats(ByVal ModuleID As Integer, ByVal TabID As Integer) As Stats
      Dim dr As IDataReader = Nothing
      Dim objStats As Stats = Nothing

      Try
        dr = DataProvider.Instance().GetStats(ModuleID)
        If dr.Read Then
          objStats = New Stats(ModuleID, TabID, dr)
        Else
          objStats = New Stats(ModuleID, TabID)
          InitializeStats(ModuleID)
        End If
      Finally
        If Not dr Is Nothing AndAlso Not dr.IsClosed Then dr.Close()
      End Try

      Return objStats
    End Function

    Public Sub RefreshStats(ByVal ModuleID As Integer)
      DataProvider.Instance().RefreshStats(ModuleID)
    End Sub

    Public Sub UpdateStats(ByVal ModuleID As Integer, ByVal Requests As Integer, ByVal Updates As Integer, _
                             ByVal MostRecentRequestID As Integer, ByVal MostRecentPostID As Integer, ByVal MostRecentAuthorID As Integer, _
                             ByVal MostRecentPostDate As DateTime, ByVal PostsToModerate As Integer)

      DataProvider.Instance().UpdateStats(ModuleID, Requests, Updates, MostRecentRequestID, MostRecentPostID, MostRecentAuthorID, _
                                             MostRecentPostDate, PostsToModerate)
    End Sub
#End Region

#End Region

#Region "Private Methods"
    Private Function FillUser(ByVal dr As IDataReader, ByVal ManageDataReader As Boolean) As UserInfo
      Dim PortalID As Integer = DotNetNuke.Entities.Portals.PortalController.GetCurrentPortalSettings.PortalId
      Dim HasData As Boolean = True
      Dim objUser As UserInfo = Nothing
      If Not dr Is Nothing Then
        Try
          If ManageDataReader Then
            HasData = dr.Read
          End If
          If HasData Then
            Dim userName As String = Null.NullString
            Dim email As String = Null.NullString
            Dim updatePassword As Boolean
            Dim isApproved As Boolean
            objUser = New UserInfo()
            With objUser
              .PortalID = PortalID
              .UserID = Convert.ToInt32(dr("UserID"))
              .FirstName = Convert.ToString(dr("FirstName"))
              .LastName = Convert.ToString(dr("LastName"))
              Try
                .DisplayName = Convert.ToString(dr("DisplayName"))
              Catch
              End Try
              .IsSuperUser = Convert.ToBoolean(dr("IsSuperUser"))
              Try
                .AffiliateID = Convert.ToInt32(Null.SetNull(dr("AffiliateID"), .AffiliateID))
              Catch
              End Try

              'store username and email in local variables for later use
              'as assigning them now will trigger a GetUser membership call

              userName = Convert.ToString(dr("Username"))
              Try
                email = Convert.ToString(dr("Email"))
              Catch
              End Try
              Try
                updatePassword = Convert.ToBoolean(dr("UpdatePassword"))
              Catch
              End Try
              If Not .IsSuperUser Then
                'For Users the approved/authorized info is stored in UserPortals
                Try
                  isApproved = Convert.ToBoolean(dr("Authorised"))
                Catch
                End Try
              End If
              .ModuleID = Convert.ToInt32(dr("ModuleID"))
              .Alias = Null.SetNullString(dr("Alias"))
              .Signature = Null.SetNullString(dr("Signature"))
              .IdentifyBy = Convert.ToInt32(dr("IdentifyBy"))
              .PageSize = Convert.ToInt32(dr("PageSize"))
              .OrderBy = CType(Null.SetNull(dr("OrderBy"), "Order_Date_DESC"), String)
              .MailFormat = CType(dr("MailFormat"), DotNetNuke.Services.Mail.MailFormat)
              .IsTrusted = Convert.ToBoolean(dr("IsTrusted"))
              .ViewableDistributions = Convert.ToInt32(dr("ViewableDistributions"))
              .IsBanned = Convert.ToBoolean(dr("IsBanned"))
              .BannedUntilDate = Null.SetNullDateTime(dr("BannedUntilDate"))
              .IsTrackingAllPosts = Convert.ToBoolean(dr("IsTrackingAllPosts"))
              .TrackingStartedDate = Null.SetNullDateTime(dr("TrackingStartedDate"))
              .Visits = Convert.ToInt32(dr("Visits"))
              .Requests = Convert.ToInt32(dr("Requests"))
              .Updates = Convert.ToInt32(dr("Updates"))
              .LastPostID = Null.SetNullInteger(dr("LastPostID"))
              .LastVisitedDate = Null.SetNullDateTime(dr("LastVisitedDate"))
              .LastPostedDate = Null.SetNullDateTime(dr("LastPostedDate"))
              .IsModerator = Convert.ToBoolean(dr("IsModerator"))
            End With
            If False Then
              'Fill Membership Property
              UserController.GetUserMembership(CType(objUser, DotNetNuke.Entities.Users.UserInfo))
            End If

            objUser.Username = userName
            objUser.Email = email
            objUser.Membership.UpdatePassword = updatePassword
            If Not objUser.IsSuperUser Then
              'SuperUser authorization is managed in aspnet Membership
              objUser.Membership.Approved = isApproved
            End If
          End If
        Finally
          If ManageDataReader And Not dr.IsClosed Then dr.Close()
        End Try
      End If
      Return objUser

    End Function


#End Region

#Region "Optional Interfaces"

    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' GetSearchItems implements the ISearchable Interface
    ''' </summary>
    ''' <remarks>
    ''' </remarks>
    ''' <param name="ModInfo">The ModuleInfo for the module to be Indexed</param>
    ''' <history>
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Function GetSearchItems(ByVal ModInfo As Entities.Modules.ModuleInfo) As DotNetNuke.Services.Search.SearchItemInfoCollection Implements DotNetNuke.Entities.Modules.ISearchable.GetSearchItems
      Dim mc As New ModuleController
      Dim settings As Hashtable = mc.GetModuleSettings(ModInfo.ModuleID)
      Dim SearchItemCollection As New SearchItemInfoCollection

      If Utilities.GetSettingValue(settings("EnableDNNSearch"), False) Then

        Dim epc As New EPrayerController
        Dim TotalRequests As Integer

        Dim ModulePath As String = DotNetNuke.Common.Globals.ApplicationPath & "/" & ModInfo.ModuleControl.ControlSrc.Substring(0, ModInfo.ModuleControl.ControlSrc.LastIndexOf("/") + 1)

        Dim objRequests As Generic.List(Of RequestInfo) = epc.GetRequests(ModInfo.ModuleID, -1, TotalRequests)
        For Each objRequest As RequestInfo In objRequests
          With objRequest
            Dim SearchItem As SearchItemInfo = New SearchItemInfo(ModInfo.ModuleTitle, RequestTypeImageHtml(.IsPraise, ModulePath) & .Subject & " (" & .Category & ")", .CreatedByUserID, _
                                                     .CreatedOnDate, ModInfo.ModuleID, .RequestID.ToString, _
                                                     .Body, "RequestId=" & .RequestID.ToString)

            SearchItemCollection.Add(SearchItem)
          End With
        Next
      End If

      Return SearchItemCollection

    End Function

    Public Function RequestTypeImageHtml(ByVal IsPraise As Boolean, ByVal ModulePath As String) As String
      Dim Src As String
      If IsPraise Then
        Src = ModulePath & "images/Praise.gif"
      Else
        Src = ModulePath & "images/Prayer.gif"
      End If
      Return "<img src='" & Src & "' border=0 hspace=2 />"
    End Function

    ''' ExportModule implements the IPortable ExportModule Interface
    ''' -----------------------------------------------------------------------------
    Public Function ExportModule(ByVal ModuleID As Integer) As String Implements DotNetNuke.Entities.Modules.IPortable.ExportModule

      Dim strXML As New StringBuilder
      Dim epc As New EPrayerController
      Dim TotalRecords As Integer
      strXML.AppendLine("<EPrayer>")

      Dim MyConfiguration As New Configuration(ModuleID)
      AppendSerializedObject(strXML, "Configuration", MyConfiguration)

      strXML.AppendLine("<Categories>")
      Dim objCategories As Generic.List(Of CategoryInfo) = epc.GetCategories(ModuleID)
      For Each objCategory As CategoryInfo In objCategories
        AppendSerializedObject(strXML, "EP_Category", objCategory)
      Next
      strXML.AppendLine("</Categories>")

      strXML.AppendLine("<Relationships>")
      Dim objRelationships As Generic.List(Of RelationshipInfo) = epc.GetRelationships()
      For Each objRelationship As RelationshipInfo In objRelationships
        AppendSerializedObject(strXML, "EP_Relationship", objRelationship)
      Next
      strXML.AppendLine("</Relationships>")

      strXML.AppendLine("<ChurchRelationships>")
      Dim objChurchRelationships As Generic.List(Of ChurchRelationshipInfo) = epc.GetChurchRelationships()
      For Each objChurchRelationship As ChurchRelationshipInfo In objChurchRelationships
        AppendSerializedObject(strXML, "EP_ChurchRelationship", objChurchRelationship)
      Next
      strXML.AppendLine("</ChurchRelationships>")

      strXML.AppendLine("<Stati>")
      Dim objStati As Generic.List(Of StatusInfo) = epc.GetStati()
      For Each objStatus As StatusInfo In objStati
        AppendSerializedObject(strXML, "EP_Status", objStatus)
      Next
      strXML.AppendLine("</Stati>")

      strXML.AppendLine("<Distributions>")
      Dim objDistributions As Generic.List(Of DistributionInfo) = epc.GetDistributions(ModuleID)
      For Each objDistribution As DistributionInfo In objDistributions
        AppendSerializedObject(strXML, "EP_Distribution", objDistribution)
      Next
      strXML.AppendLine("</Distributions>")

      strXML.AppendLine("<Users>")
      Dim objUsers As Generic.List(Of UserInfo) = epc.GetUsers(ModuleID, TotalRecords)
      For Each objUser As UserInfo In objUsers
        AppendEPrayerUserObject(strXML, "User", objUser)
      Next
      strXML.AppendLine("</Users>")

      strXML.AppendLine("<Moderators>")
      Dim objModerators As Generic.List(Of ModeratorInfo) = epc.GetModerators(ModuleID, False)
      For Each objModerator As ModeratorInfo In objModerators
        AppendEPrayerModeratorObject(strXML, "Moderator", objModerator)
      Next
      strXML.AppendLine("</Moderators>")

      Dim objRequests As Generic.List(Of RequestInfo) = epc.GetRequests(ModuleID, -1, TotalRecords)
      If objRequests.Count > 0 Then
        strXML.AppendLine("<Requests>")
        For Each objRequest As RequestInfo In objRequests
          objRequest.Posts.AddRange(epc.GetPosts(objRequest.RequestID, Integer.MaxValue, True))
          AppendSerializedObject(strXML, "Request", objRequest)
        Next
        strXML.AppendLine("</Requests>")
        strXML.AppendLine("</EPrayer>")
      End If

      Return strXML.ToString

    End Function

    Private Sub AppendSerializedObject(ByVal sb As StringBuilder, ByVal Tag As String, ByVal obj As Object)

      Try
        Dim xser As Xml.Serialization.XmlSerializer
        Dim sw As New IO.StringWriter
        Dim xmlDoc As New Xml.XmlDocument
        Dim xmlNode As Xml.XmlNode
        Dim objType As Type = obj.GetType

        xser = New Xml.Serialization.XmlSerializer(objType)
        xser.Serialize(sw, obj)
        xmlDoc.LoadXml(sw.GetStringBuilder().ToString())
        xmlNode = xmlDoc.SelectSingleNode(Tag)
        xmlNode.Attributes.Remove(xmlNode.Attributes.ItemOf("xmlns:xsd"))
        xmlNode.Attributes.Remove(xmlNode.Attributes.ItemOf("xmlns:xsi"))
        sb.Append(xmlNode.OuterXml)
      Catch ex As Exception
        Dim msg As String = ex.Message
      End Try
    End Sub

    Private Sub AppendElement(ByVal sb As StringBuilder, ByVal Tag As String, ByVal Value As Object)
      sb.AppendFormat("<{0}>", Tag)
      sb.Append(Value)
      sb.AppendFormat("</{0}>", Tag)
    End Sub

    Private Sub AppendEPrayerUserObject(ByVal sb As StringBuilder, ByVal Tag As String, ByVal User As UserInfo)
      If Not User Is Nothing Then
        sb.AppendFormat("<{0}>", Tag)
        With User
          AppendElement(sb, "Username", .Username)
          AppendElement(sb, "Alias", .[Alias])
          AppendElement(sb, "Signature", XmlUtils.XMLEncode(.Signature))
          AppendElement(sb, "IdentifyBy", .IdentifyBy)
          AppendElement(sb, "PageSize", .PageSize)
          AppendElement(sb, "OrderBy", .OrderBy)
          AppendElement(sb, "MailFormat", .MailFormat)
          AppendElement(sb, "ViewableDistributions", .ViewableDistributions)
          AppendElement(sb, "IsTrusted", .IsTrusted)
          AppendElement(sb, "IsBanned", .IsBanned)
          AppendElement(sb, "BannedUntilDate", .BannedUntilDate)
          AppendElement(sb, "IsTrackingAllPosts", .IsTrackingAllPosts)
          AppendElement(sb, "TrackingStartedDate", .TrackingStartedDate)
          AppendElement(sb, "Visits", .Visits)
          AppendElement(sb, "Requests", .Requests)
          AppendElement(sb, "Updates", .Updates)
          AppendElement(sb, "LastVisitedDate", .LastVisitedDate)
          AppendElement(sb, "LastPostedDate", .LastPostedDate)
        End With
        sb.AppendFormat("</{0}>", Tag)
      End If
    End Sub

    Private Sub AppendEPrayerModeratorObject(ByVal sb As StringBuilder, ByVal Tag As String, ByVal Moderator As ModeratorInfo)
      If Not Moderator Is Nothing Then
        sb.AppendFormat("<{0}>", Tag)
        With Moderator
          AppendElement(sb, "Username", .Username)
          AppendElement(sb, "AssignedDate", .AssignedDate)
          AppendElement(sb, "ExpiresDate", .ExpiresDate)
          AppendElement(sb, "PostsModerated", .PostsModerated)
          AppendElement(sb, "LastModeratedDate", .LastModeratedDate)
          AppendElement(sb, "IsSuspended", .IsSuspended)
        End With
        sb.AppendFormat("</{0}>", Tag)
      End If
    End Sub


    ''' ImportModule implements the IPortable ImportModule Interface
    ''' -----------------------------------------------------------------------------
    Public Sub ImportModule(ByVal ModuleID As Integer, ByVal Content As String, ByVal Version As String, ByVal UserId As Integer) Implements DotNetNuke.Entities.Modules.IPortable.ImportModule
      Dim ps As PortalSettings = New DotNetNuke.Entities.Portals.PortalSettings()
      Dim PortalID As Integer = ps.PortalId

      Try
        Dim ForeignKeyTranslator As New System.Collections.Specialized.NameValueCollection
        Dim Node, RNode, SCNode, PNode As XmlNode
        Dim xmlDocuments As XmlNode = GetContent(Content, "EPrayer")

        Dim MyConfiguration As New Configuration(ModuleID)
        Node = xmlDocuments.SelectSingleNode("Configuration")
        With MyConfiguration
          .AdminEmail = Node.Item("AdminEmail").InnerText
          .AllowOwnPostDeletion = Convert.ToBoolean(Node.Item("AllowOwnPostDeletion").InnerText)
          .RequestLifespan = Convert.ToInt32(Node.Item("RequestLifespan").InnerText)
          .AllowOwnPostEditing = Convert.ToBoolean(Node.Item("AllowOwnPostEditing").InnerText)
          .AnonymousUsersViewableDistributions = Convert.ToInt32(Node.Item("AnonymousUsersViewableDistributions").InnerText)
          .EnableDNNSearch = Convert.ToBoolean(Node.Item("EnableDNNSearch").InnerText)
          .EnableModeration = Convert.ToBoolean(Node.Item("EnableModeration").InnerText)
          .EnableNotification = Convert.ToBoolean(Node.Item("EnableNotification").InnerText)
          .EnableSubjectContact = Convert.ToBoolean(Node.Item("EnableSubjectContact").InnerText)
          .EnableSubjectNotification = Convert.ToBoolean(Node.Item("EnableSubjectNotification").InnerText)
          .MailFormat = CType([Enum].Parse(GetType(DotNetNuke.Services.Mail.MailFormat), Node.Item("MailFormat").InnerText), DotNetNuke.Services.Mail.MailFormat)
          .MailSendMethod = CType([Enum].Parse(GetType(MailManager.MailSendMethods), Node.Item("MailSendMethod").InnerText), MailManager.MailSendMethods)
          .MailStyleName = Node.Item("MailStyleName").InnerText
          .MaxBodyLength = Convert.ToInt32(Node.Item("MaxBodyLength").InnerText)
          .NewUsersAreTrusted = Convert.ToBoolean(Node.Item("NewUsersAreTrusted").InnerText)
          .NewUsersViewableDistributions = Convert.ToInt32(Node.Item("NewUsersViewableDistributions").InnerText)
          .PageSize = Convert.ToInt32(Node.Item("PageSize").InnerText)
          .TrackNewPosts = Convert.ToBoolean(Node.Item("TrackNewPosts").InnerText)
          .TrackViews = Convert.ToBoolean(Node.Item("TrackViews").InnerText)
          .TrackVisits = Convert.ToBoolean(Node.Item("TrackVisits").InnerText)
          '.SaveSettings()
        End With

        Dim epc As New EPrayerController

        Dim objCategory As CategoryInfo
        For Each Node In xmlDocuments.SelectNodes("Categories/EP_Category")
          objCategory = New CategoryInfo
          With objCategory
            If Convert.ToBoolean(Node.Attributes("IsGlobal").InnerText) Then
              .ModuleID = -1
            Else
              .ModuleID = ModuleID
            End If
            .Category = Node.Item("Category").InnerText
            .ViewOrder = Integer.Parse(Node.Item("ViewOrder").InnerText)
          End With
          Try
            epc.AddCategory(objCategory)
          Catch ex As Exception
            '
          End Try
        Next
        For Each objCategory In epc.GetCategories(ModuleID)
          ForeignKeyTranslator.Add("CAT-" & objCategory.Category, objCategory.CategoryID.ToString)
        Next

        Dim objRelationship As RelationshipInfo
        For Each Node In xmlDocuments.SelectNodes("Relationships/EP_Relationship")
          objRelationship = New RelationshipInfo
          With objRelationship
            .Relationship = Node.Item("Relationship").InnerText
            .ViewOrder = Integer.Parse(Node.Item("ViewOrder").InnerText)
          End With
          Try
            epc.AddRelationship(objRelationship)
          Catch ex As Exception
            '
          End Try
        Next
        For Each objRelationship In epc.GetRelationships()
          ForeignKeyTranslator.Add("REL-" & objRelationship.Relationship, objRelationship.RelationshipID.ToString)
        Next

        Dim objChurchRelationship As ChurchRelationshipInfo
        For Each Node In xmlDocuments.SelectNodes("ChurchRelationships/EP_ChurchRelationship")
          objChurchRelationship = New ChurchRelationshipInfo
          With objChurchRelationship
            .ChurchRelationship = Node.Item("ChurchRelationship").InnerText
            .ViewOrder = Integer.Parse(Node.Item("ViewOrder").InnerText)
          End With
          Try
            epc.AddChurchRelationship(objChurchRelationship)
          Catch ex As Exception
            '
          End Try
        Next
        For Each objChurchRelationship In epc.GetChurchRelationships()
          ForeignKeyTranslator.Add("CHREL-" & objChurchRelationship.ChurchRelationship, objChurchRelationship.ChurchRelationshipID.ToString)
        Next

        Dim objStatus As StatusInfo
        For Each Node In xmlDocuments.SelectNodes("Stati/EP_Status")
          objStatus = New StatusInfo
          With objStatus
            .Status = Node.Item("Status").InnerText
            .ViewOrder = Integer.Parse(Node.Item("ViewOrder").InnerText)
          End With
          Try
            epc.AddStatus(objStatus)
          Catch ex As Exception
            '
          End Try
        Next
        For Each objStatus In epc.GetStati()
          ForeignKeyTranslator.Add("STAT-" & objStatus.Status, objStatus.StatusID.ToString)
        Next

        Dim objDistribution As DistributionInfo
        For Each Node In xmlDocuments.SelectNodes("Distributions/EP_Distribution")
          objDistribution = New DistributionInfo
          With objDistribution
            If Convert.ToBoolean(Node.Attributes("IsGlobal").InnerText) Then
              .ModuleID = -1
            Else
              .ModuleID = ModuleID
            End If
            .DistributionID = Convert.ToInt32(Node.Item("DistributionID").InnerText)
            .Distribution = Node.Item("Distribution").InnerText
            .ViewOrder = Integer.Parse(Node.Item("ViewOrder").InnerText)
          End With
          Try
            epc.AddDistribution(objDistribution)
          Catch ex As Exception
            '
          End Try
        Next

        For Each Node In xmlDocuments.SelectNodes("Users/User")
          Dim uid As Integer = GetUserIDByName(Node.Item("Username").InnerText, PortalID)
          If uid <> -1 Then
            Dim objUser As New UserInfo
            With objUser
              .Alias = Null.SetNullString(Node.Item("Alias").InnerText)
              .Signature = Null.SetNullString(Node.Item("Signature").InnerText)
              .IdentifyBy = Convert.ToInt32(Node.Item("IdentifyBy").InnerText)
              .PageSize = Convert.ToInt32(Node.Item("PageSize").InnerText)
              .OrderBy = Node.Item("OrderBy").InnerText
              .MailFormat = CType([Enum].Parse(GetType(DotNetNuke.Services.Mail.MailFormat), Node.Item("MailFormat").InnerText), DotNetNuke.Services.Mail.MailFormat)
              .ViewableDistributions = Convert.ToInt32(Node.Item("ViewableDistributions").InnerText)
              .IsTrusted = Convert.ToBoolean(Node.Item("IsTrusted").InnerText)
              .IsBanned = Convert.ToBoolean(Node.Item("IsBanned").InnerText)
              .BannedUntilDate = Null.SetNullDateTime(Node.Item("BannedUntilDate").InnerText)
              .IsTrackingAllPosts = Convert.ToBoolean(Node.Item("IsTrackingAllPosts").InnerText)
              .TrackingStartedDate = Null.SetNullDateTime(Node.Item("TrackingStartedDate").InnerText)
              .Visits = Convert.ToInt32(Node.Item("Visits").InnerText)
              .Requests = Convert.ToInt32(Node.Item("Requests").InnerText)
              .Updates = Convert.ToInt32(Node.Item("Updates").InnerText)
              .LastVisitedDate = Null.SetNullDateTime(Node.Item("LastVisitedDate").InnerText)
              .LastPostedDate = Null.SetNullDateTime(Node.Item("LastPostedDate").InnerText)
              Try

                'Need AddUser overload to include ALL other fields: Signature, IdentifyBy, IsBanned, BannedUntilDate
                '(IsTrackingAllPosts, TrackingStartedDate), Visits, Requests, Updates, LastVisitedDate, LastPostedDate !!!

                epc.AddUser(ModuleID, uid, .Alias, .PageSize, .OrderBy, .MailFormat, .ViewableDistributions, .IsTrusted)
                epc.UpdateUser(objUser)
                epc.StartEndTrackingAllPosts(ModuleID, uid, .IsTrackingAllPosts)
              Catch ex As Exception
                'Eat the exception - most likely because user already exists
              End Try

            End With
          End If
        Next

        For Each Node In xmlDocuments.SelectNodes("Moderators/Moderator")
          Dim uid As Integer = GetUserIDByName(Node.Item("Username").InnerText, PortalID)
          If uid <> -1 Then
            Dim objModerator As New ModeratorInfo
            With objModerator
              .AssignedDate = Null.SetNullDateTime(Node.Item("AssignedDate").InnerText)
              .ExpiresDate = Null.SetNullDateTime(Node.Item("ExpiresDate").InnerText)
              .PostsModerated = Convert.ToInt32(Node.Item("PostsModerated").InnerText)
              .LastModeratedDate = Null.SetNullDateTime(Node.Item("LastModeratedDate").InnerText)
              .IsSuspended = Convert.ToBoolean(Node.Item("IsSuspended").InnerText)
              Try
                'Need overloaded AddModerator to include ALL other fields:
                'AssignedDate, PostsModerated, LastModeratedDate, IsSuspended
                epc.AddModerator(ModuleID, uid, .ExpiresDate)

              Catch ex As Exception
                'Eat the exception - most likely because moderator already exists
              End Try
            End With
          End If
        Next

        For Each RNode In xmlDocuments.SelectNodes("Requests/Request")
          Dim objRequest As New RequestInfo
          With objRequest
            .ModuleID = ModuleID
            .CategoryID = Convert.ToInt32(ForeignKeyTranslator("CAT-" & RNode.Item("Category").InnerText))
            .IsPraise = Convert.ToBoolean(RNode.Item("IsPraise").InnerText)
            .Subject = RNode.Item("Subject").InnerText
            .Views = Convert.ToInt32(RNode.Item("Views").InnerText)
            .Updates = Convert.ToInt32(RNode.Item("Updates").InnerText)
            .StatusID = Convert.ToInt32(ForeignKeyTranslator("STAT-" & RNode.Item("Status").InnerText))
            .Expires = Convert.ToDateTime(RNode.Item("Expires").InnerText)
            .IsLocked = Convert.ToBoolean(RNode.Item("IsLocked").InnerText)
            .LastPostDate = Convert.ToDateTime(RNode.Item("LastPostDate").InnerText)
            SCNode = RNode.SelectSingleNode("SubjectContact")
            If Not SCNode Is Nothing Then
              .SubjectContact = New SubjectContactInfo()
              With .SubjectContact
                .Name = Null.SetNullString(SCNode.Item("Name").InnerText)
                .Address = Null.SetNullString(SCNode.Item("Address").InnerText)
                .City = Null.SetNullString(SCNode.Item("City").InnerText)
                .State = Null.SetNullString(SCNode.Item("State").InnerText)
                .ZipPlus4 = Null.SetNullString(SCNode.Item("ZipPlus4").InnerText)
                .EMail = Null.SetNullString(SCNode.Item("EMail").InnerText)
              End With
            End If
            .ChurchRelationshipID = Convert.ToInt32(ForeignKeyTranslator("CHREL-" & RNode.Item("ChurchRelationship").InnerText))
          End With
          For Each PNode In RNode.SelectNodes("Posts/Post")
            Dim objPost As New PostInfo
            Dim createdByUserID As Integer = -1
            Dim lastModifiedByUserID As Integer = -1
            Dim createdOnDate As DateTime = DateTime.Now()
            Dim lastModifiedOnDate As DateTime = DateTime.Now()

            With objPost
              .IsApproved = Convert.ToBoolean(PNode.Item("IsApproved").InnerText)
              If PNode.Item("ApprovedDate") IsNot Nothing Then
                .ApprovedOnDate = Null.SetNullDateTime(PNode.Item("ApprovedDate").InnerText)
              Else
                .ApprovedOnDate = Null.SetNullDateTime(PNode.Item("ApprovedOnDate").InnerText)
              End If
              If PNode.Item("CreatedByUsername") IsNot Nothing Then
                createdByUserID = GetUserIDByName(PNode.Item("CreatedByUsername").InnerText, PortalID)
              ElseIf PNode.Item("CreatedByUser") IsNot Nothing Then
                createdByUserID = GetUserIDByName(PNode.Item("CreatedByUser").InnerText, PortalID)
              End If
              If PNode.Item("CreatedDate") IsNot Nothing Then
                createdOnDate = Convert.ToDateTime(PNode.Item("CreatedDate").InnerText)
              Else
                createdOnDate = Convert.ToDateTime(PNode.Item("CreatedOnDate").InnerText)
              End If
              If PNode.Item("EditedByUser") IsNot Nothing Then
                lastModifiedByUserID = GetUserIDByName(PNode.Item("EditedByUser").InnerText, PortalID)
              ElseIf PNode.Item("LastModifiedByUsername") IsNot Nothing Then
                lastModifiedByUserID = GetUserIDByName(PNode.Item("LastModifiedByUsername").InnerText, PortalID)
              End If
              If PNode.Item("EditedDate") IsNot Nothing Then
                lastModifiedOnDate = Null.SetNullDateTime(PNode.Item("EditedDate").InnerText)
              Else
                lastModifiedOnDate = Null.SetNullDateTime(PNode.Item("LastModifiedOnDate").InnerText)
              End If
              .NotifySubject = Convert.ToBoolean(PNode.Item("NotifySubject").InnerText)
              .RemoteAddr = PNode.Item("RemoteAddr").InnerText
              .SubmittedFor = Null.SetNullString(PNode.Item("SubmittedFor").InnerText)
              .Body = PNode.Item("Body").InnerText
              .Distribution = Convert.ToInt32(PNode.Item("Distribution").InnerText)
              .RelationshipID = Convert.ToInt32(ForeignKeyTranslator("REL-" & PNode.Item("Relationship").InnerText))
            End With
            epc.AddPost(objRequest, objPost, createdByUserID, createdOnDate, lastModifiedByUserID, lastModifiedOnDate)
          Next
        Next
      Catch exc As Exception
        Dim Msg As String = exc.Message
      End Try
    End Sub

    Public Function GetUserIDByName(ByVal Username As String, ByVal PortalID As Integer) As Integer
      Dim UserID As Integer = -1
      If Not String.IsNullOrEmpty(Username) Then
        Dim DNNui As DotNetNuke.Entities.Users.UserInfo = DotNetNuke.Entities.Users.UserController.GetUserByName(PortalID, Username)
        If Not DNNui Is Nothing Then UserID = DNNui.UserID
      End If
      Return UserID
    End Function

    Public Function UpgradeModule(ByVal Version As String) As String Implements DotNetNuke.Entities.Modules.IUpgradeable.UpgradeModule
      Dim Result As String = ""
      Dim dmc As New DesktopModuleController
      Dim dmi As Entities.Modules.DesktopModuleInfo = DesktopModuleController.GetDesktopModuleByModuleName(Consts.ModuleName, -1)
      If dmi Is Nothing Then
        Result = Version & " - failure to obtain DesktopModuleInfo object for ModuleName " & Consts.ModuleName
      Else
        Dim mdc As New Entities.Modules.Definitions.ModuleDefinitionController
        Dim mdi As Entities.Modules.Definitions.ModuleDefinitionInfo = Definitions.ModuleDefinitionController.GetModuleDefinitionByFriendlyName(dmi.FriendlyName, dmi.DesktopModuleID)
        If mdi Is Nothing Then
          Result = Version & " - failure to obtain ModuleDefinitionInfo object for Definition FriendlyName " & dmi.FriendlyName
        Else
          Dim ModuleDefID As Integer = mdi.ModuleDefID
          If Version = "04.00.00" Then
            ' Custom permissions now created by DNN 5 Manifest
          Else
            Dim DestFilepath As String = DotNetNuke.Common.Globals.ApplicationMapPath & "\DesktopModules\" & dmi.FolderName & "\Templates\"
            Dim SrcFilepath As String = String.Empty
            Try
              SrcFilepath = DotNetNuke.Common.Globals.ApplicationMapPath & "\DesktopModules\" & dmi.FolderName & "\" & Localization.LocalResourceDirectory & "\Templates\"
              If Version >= "04.02.01" AndAlso Directory.Exists(SrcFilepath) Then
                For Each srcPath As String In Directory.GetFiles(SrcFilepath, "EMail.*")
                  Dim dstPath As String = DestFilepath & Path.GetFileName(srcPath)
                  If Not File.Exists(dstPath) Then File.Copy(srcPath, dstPath)
                Next
                Directory.Delete(SrcFilepath, True)
                Result = Version & " - Moved " & SrcFilepath & "Email.* to " & DestFilepath & "EMail.* and deleted folder " & SrcFilepath
              Else
                DestFilepath = DestFilepath & "EMail.xml"
                SrcFilepath = DotNetNuke.Common.Globals.ApplicationMapPath & "\DesktopModules\" & dmi.FolderName & "\Templates\TempEMail.xml"
                If File.Exists(DestFilepath) Then
                  Result = String.Empty
                Else
                  File.Copy(SrcFilepath, DestFilepath)
                  Result = Version & " - Temporary email template file " & SrcFilepath & " renamed to " & DestFilepath
                End If
                File.Delete(SrcFilepath)
              End If
            Catch ex As Exception
              Result = Version & " - Unable to rename or move email template file from " & SrcFilepath & " to " & DestFilepath
            End Try
            If Version = "04.02.01" Then
              Dim mc As New DotNetNuke.Entities.Modules.ModuleController
              Dim mi As DotNetNuke.Entities.Modules.ModuleInfo
              Dim arrModuleInfo As ArrayList = mc.GetAllModules()
              Dim ModuleStatsUpgraded As Integer = 0
              If arrModuleInfo.Count > 0 Then
                Dim epc As New EPrayerController
                For Each mi In arrModuleInfo
                  If (mi.DesktopModuleID = dmi.DesktopModuleID) _
                        AndAlso (mi.ModuleDefID = mdi.ModuleDefID) Then
                    DataProvider.Instance().UpgradeStats(mi.ModuleID)
                    ModuleStatsUpgraded += 1
                  End If
                Next
                If ModuleStatsUpgraded > 0 Then
                  Result = Result & "<br />" & Version & " - " & String.Format("Upgraded stats of {0} existing modules", ModuleStatsUpgraded)
                End If
              End If
            End If
          End If
        End If
      End If
      Return Result
    End Function
#End Region

  End Class
End Namespace
